#ifndef FILEPATH_H_INCLUDED
#define FILEPATH_H_INCLUDED

#include "Atomic.h"

namespace CEngine
{

///
///A class that deals with file paths.
///
class FilePath {
    public:

        ///Blank constructor. Sets length to 0,
        ///and the pointer to NULL.
        FilePath(void);

        ///String constructor. Copies the string pointed to by path,
        ///scans the length of the string until \0, and calls processPath depending on process.
        FilePath(CHAR* path, bool process = true);

        ///Copy constructor. Copies the contents of path.
        FilePath(const FilePath& path);

        ///Copy operator. Creates a copy of path.
        FilePath&
        operator= (const FilePath& path);

        ///Set operator. Copies the string pointed to by path,
        ///and scans the length of the string until \0.
        FilePath&
        operator= (CHAR* path);

        ///Destructor.
        ~FilePath(void);

        ///Path comparison. Compares two paths to see if they are the same.
        bool
        operator== (const FilePath& path);

        ///Path comparison. Compares a path and a string to see if they are the same.
        bool
        operator== (CHAR* path);

        ///Converts a path to work with the OS via converting the separators to the OS's,
        ///removes consecutive separators, and returns the new length.
        ///Path cannot be constant!
        static U32
        processPath(CHAR* path);

        ///Returns the path pointer,
        ///and the length of it (can be NULL).
        CHAR*
        getFullPath(U32* length = NULL) const;

        ///Returns just the filename (and optionally the extension too),
        ///and the length of it including/excluding the extension based on includeExtension (can be NULL).
        CHAR*
        getFileName(U32* length = NULL, bool includeExtension = true) const;

        ///Returns just the extension (ex: ".txt"),
        ///and the length of it (can be NULL).
        ///Returns the terminating \0 (length is 0) if there is no extension.
        CHAR*
        getExtension(U32* length = NULL) const;

        ///Returns the drive letter for a path
        ///or \0 if there was none.
        CHAR
        getDriveLetter(void) const;

        ///Returns the length of the path.
        U32
        getLength(void) const;

        ///Removes . and .. elements from the path,
        ///sets the new length, and returns the change from the old length.
        I32
        simplifyPath(void);

        ///Returns true if the path is a valid file or directory.
        bool
        pathExists(void) const;

        ///Returns true if the path is relative.
        bool
        isRelative(void) const;

        ///Returns true if the path is a valid directory.
        bool
        isDirectory(void) const;

    private:

        CHAR* path;
        U32   length;

        CHAR* getFileNamePrivate(CHAR array[], U32* length, bool includeExtension) const;
};

inline CHAR*
FilePath::getFullPath(U32* l) const {
    if(l)
       *l = length;
    return path;
}

inline U32
FilePath::getLength(void) const {
    return length;
}

}

#endif // PATH_H_INCLUDED
